import os
import sys
import time
import argparse
import base64
import random
sys.path.append(os.getcwd())

import svgwrite
import json
from PIL import Image

from utils.font_size import *
from utils.image import *
from utils.platform import *
from utils.io import *
from components.rect import *
from components.exit import *
from components.factory import *
from settings import *

assert is_windows() or is_darwin()

def gen_common(data, theme_type):
    exit_height = 50 * SCALE
    min_width = 250 * SCALE
    min_height = 250 * SCALE

    space_size = 20 * SCALE
    safe_area_size = 8 * SCALE
    text_size = 40 * SCALE

    content_width = min_width
    content_height = min_height + exit_height + 2 * safe_area_size

    theme_color = THEME_MAP.get(theme_type) or COLOR_GREEN
    obj_type = data.get('type')

    # exit
    if obj_type == 0:
        bottom_name = 'forward'
    else:
        exit_info = data.get('exit')
        exit_seq = exit_info.get('seq') or ''
        exit_sub = exit_info.get('sub') or ''
        if obj_type == -1:
            exit_item = ExitComponent(theme_color, True, exit_seq, exit_sub)
            bottom_name = 'forward'
        elif obj_type == -2:
            exit_item = ExitComponent(theme_color, True, exit_seq, exit_sub)
            bottom_name = 'left'
        elif obj_type == 1:
            exit_item = ExitComponent(theme_color, False, exit_seq, exit_sub)
            bottom_name = 'exit'
        exit_height = exit_item.height()

    data_file_name = '{}_{}_{}'.format(bottom_name, time.strftime('%Y%m%d%H%M%S'), random.randint(0, 9999))
    svg_file_path = './output/{}.svg'.format(data_file_name)
    png_file_path = './output/{}.png'.format(data_file_name)

    # lines
    lines = data.get('lines')
    line_heights = []

    ele_lines = []

    for line in lines:
        line_height = 0
        line_width = (len(line) + 1) * space_size

        ele_line = []
        for item in line:
            item_type = item.get('type')
            item_info = item.get('info')

            factory = ComponentFactory(text_size, COLOR_WHITE)
            ele = factory.component(item_type, item_info)
            
            ele_line.append(ele)
            line_height = max(line_height, ele.height())
            line_width += ele.width()
        
        content_width = max(content_width, line_width)
        line_heights.append(line_height)
        ele_lines.append(ele_line)

    content_height = max(content_height, sum(line_heights) + 2 * exit_height + (len(line_heights) + 2) * space_size + 2 * safe_area_size)

    # rect
    dwg = svgwrite.Drawing(svg_file_path, profile='tiny', width=content_width, height=content_height)

    if obj_type == 1:
        exit_item.draw(dwg, content_width - exit_item.width(), 0)
    elif obj_type == -2 or obj_type == -1:
        exit_item.draw(dwg, 0, 0)

    bg_rect = DoubleStrokeRectComponent(width=content_width, height=content_height - exit_height, main_color=theme_color, stroke_color=COLOR_WHITE, stroke_width=4 * SCALE, r=16 * SCALE)
    bg_rect.draw(dwg, 0, exit_height)

    valid_height = content_height - 2 * exit_height - 2 * safe_area_size - space_size
    real_vertical_space = (valid_height - sum(line_heights)) / (len(line_heights) + 1)
    current_line_y = exit_height + safe_area_size
    for (eles, current_line_height) in zip(ele_lines, line_heights):
        current_line_y += real_vertical_space
        ele_count = len(eles)
        real_horizontal_space = (content_width - sum(ele.width() for ele in eles)) / (ele_count + 1)
        current_row_x = 0
        for ele in eles:
            current_row_x += real_horizontal_space
            ele_y = current_line_y + (current_line_height - ele.height()) / 2
            ele.draw(dwg, current_row_x, ele_y)
            current_row_x += ele.width()
        current_line_y += current_line_height

    # export
    svg2png(dwg, content_width, content_height, svg_file_path, png_file_path)

    # additional element
    # open the image
    src_file_path = './resources/{}.png'.format(bottom_name)
    dst = Image.open(png_file_path)
    src = Image.open(src_file_path)
    src = src.resize((int(exit_height), int(exit_height)))
    src_x = int((content_width - exit_height) / 2)
    src_y = int(content_height - space_size - safe_area_size - exit_height)
    dst.paste(src, (src_x, src_y), src)
    save_image(dst, png_file_path)
    with open(png_file_path, "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
    return encoded_string, png_file_path


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--data', dest='Data', type=str, default='./example/exit.json', help='Path of json data file.')
    parser.add_argument('-c', '--color', dest='Color', type=str, default='g', help='Theme color.')
    args = parser.parse_args()
    data_file_path = args.Data
    theme_type = args.Color
    with open(data_file_path, 'r', encoding='utf8') as file:
        data = json.load(file)
    gen_common(data, theme_type)